【精选】seata + nacos + springboot 配置和使用 |
您所在的位置:网站首页 › seata server › 【精选】seata + nacos + springboot 配置和使用 |
一.seata 分布式事务
seata是什么?
Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案。
seata术语
TC (Transaction Coordinator) - 事务协调者:维护全局和分支事务的状态,驱动全局事务提交或回滚TM (Transaction Manager) - 事务管理器:定义全局事务的范围:开始全局事务、提交或回滚全局事务。RM (Resource Manager) - 资源管理器:管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。TM 和 RM 是作为 Seata 的客户端与业务系统集成在一起,TC 作为 Seata 的服务端独立部署(即:seata-server)
seata AT模式 前提条件
基于支持本地 ACID 事务的关系型数据库Java 应用,通过 JDBC 访问数据库
Seata 中,分布式事务的执行流程:
TM 开启分布式事务(TM 向 TC 注册全局事务记录);按业务场景,编排数据库、服务等事务内资源(RM 向 TC 汇报资源准备状态 );TM 结束分布式事务,事务一阶段结束(TM 通知 TC 提交/回滚分布式事务);TC 汇总事务信息,决定分布式事务是提交还是回滚;TC 通知所有 RM 提交/回滚 资源,事务二阶段结束。
原理(TM和RM都会被seate代理数据源):
TM执行业务时,会通过aop拦截@GlobalTransactional注解,先查询ThreadLocal是否有XID,如果没有,会请求TC创建一个XID,获取到XID,保存到ThreadLocal;在调用其他服务接口的时候,会把XID存放到Http请求头传给RM;RM从请求头上获取到XID,会保存到Threadlocal,并且向TC注册事务分支(当前微服务的);RM操作sql前,会记录前置镜像到undo_log表,然后执行sql,成功后再记录后置镜像到undo_log表(记录undo_log和执行业务sql是同一事务),然后提交事务;TM调用RM返回,继续执行业务,如果异常,通知TC,然后TC通知所有事务分支进行回滚;RM收到回滚通知,会执行后置镜像sql,将数据还原,然后删除当前XID中undo_log的镜像记录;如果成功,通知TC,然后TC通知所有事务分支;RM收到成功通知,删除当前XID中undo_log的镜像记录;
seata AT模式
AT模式一阶段: 在一阶段,Seata 会拦截“业务 SQL”,首先解析 SQL 语义,找到“业务 SQL”要更新的业务数据,在业务数据被更新前,将其保存成“before image”,然后执行“业务 SQL”更新业务数据,在业务数据更新之后,再将其保存成“after image”,最后生成行锁。以上操作全部在一个数据库事务内完成,这样保证了一阶段操作的原子性AT模式二阶段: 二阶段如果是提交的话,因为“业务 SQL”在一阶段已经提交至数据库, 所以 Seata 框架只需将一阶段保存的快照数据和行锁删掉,完成数据清理即可 二阶段如果是回滚的话,Seata 就需要回滚一阶段已经执行的“业务 SQL”,还原业务数据。回滚方式便是用“before image”还原业务数据;但在还原前要首先要校验脏写,对比“数据库当前业务数据”和 “after image”,如果两份数据完全一致就说明没有脏写,可以还原业务数据,如果不一致就说明有脏写,出现脏写就需要转人工处理
二.环境配置
nacos 版本 : nacos-server-2.0.3seata 版本 : seata-server-1.4.0SpringBoot 版本 : 2.4.5SpringCloud 版本 : 2021.1seata-sql文件下载地址
-- the table to store GlobalSession data
CREATE TABLE IF NOT EXISTS `global_table`
(
`xid` VARCHAR(128) NOT NULL,
`transaction_id` BIGINT,
`status` TINYINT NOT NULL,
`application_id` VARCHAR(32),
`transaction_service_group` VARCHAR(32),
`transaction_name` VARCHAR(128),
`timeout` INT,
`begin_time` BIGINT,
`application_data` VARCHAR(2000),
`gmt_create` DATETIME,
`gmt_modified` DATETIME,
PRIMARY KEY (`xid`),
KEY `idx_status_gmt_modified` (`status` , `gmt_modified`),
KEY `idx_transaction_id` (`transaction_id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4;
-- the table to store BranchSession data
CREATE TABLE IF NOT EXISTS `branch_table`
(
`branch_id` BIGINT NOT NULL,
`xid` VARCHAR(128) NOT NULL,
`transaction_id` BIGINT,
`resource_group_id` VARCHAR(32),
`resource_id` VARCHAR(256),
`branch_type` VARCHAR(8),
`status` TINYINT,
`client_id` VARCHAR(64),
`application_data` VARCHAR(2000),
`gmt_create` DATETIME(6),
`gmt_modified` DATETIME(6),
PRIMARY KEY (`branch_id`),
KEY `idx_xid` (`xid`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4;
-- the table to store lock data
CREATE TABLE IF NOT EXISTS `lock_table`
(
`row_key` VARCHAR(128) NOT NULL,
`xid` VARCHAR(128),
`transaction_id` BIGINT,
`branch_id` BIGINT NOT NULL,
`resource_id` VARCHAR(256),
`table_name` VARCHAR(32),
`pk` VARCHAR(36),
`status` TINYINT NOT NULL DEFAULT '0' COMMENT '0:locked ,1:rollbacking',
`gmt_create` DATETIME,
`gmt_modified` DATETIME,
PRIMARY KEY (`row_key`),
KEY `idx_status` (`status`),
KEY `idx_branch_id` (`branch_id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4;
-- 业务库undo_log表
CREATE TABLE `undo_log` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`branch_id` bigint(20) NOT NULL,
`xid` varchar(100) NOT NULL,
`context` varchar(128) NOT NULL,
`rollback_info` longblob NOT NULL,
`log_status` int(11) NOT NULL,
`log_created` datetime NOT NULL,
`log_modified` datetime NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
seata-server 下载 seata-server下载地址 修改配置文件 解压下载后的seata-server,进入conf目录 修改file.conf 修改registry.conf 创建并修改config.text config.text下载地址
将修改后的 config.text 放入seata-server的根目录 导入nacos-config.sh nacos-config.sh下载地址 将下载后的nacos-config.sh放入seata的conf目录 使用git执行导入命令: sh nacos-config.sh -h localhost -p 8848 -g SEATA_GROUP -t 0af6e97b-a684-4647-b696-7c6d42aecce7 -u nacos -w nacos 命令解析:-h -p 指定nacos的端口地址;-g 指定配置的分组,注意,是配置的分组;-t 指定命名空间id; -u -w指定nacos的用户名和密码,同样,这里开启了nacos注册和配置认证的才需要指定 导入原因:config.txt就是seata各种详细的配置,执行 nacos-config.sh 即可将这些配置导入到nacos,这样就不需要将file.conf和registry.conf放到我们的项目中了,需要什么配置就直接从nacos中读取。注意,config.text有差不多三四条 xxx.xx.xx = (没有值的配置)需要删除,不然上传会报错。 导入成功后,可以在nacos页面看到各种配置(config.text的内容): 依次启动nacos,seata-server,项目,可在seata-server 控制台看到 RM注册成功的日志 SpringCloud xid无法传递 ,远程服务事务无法回滚 ? 首先确保你引入了spring-cloud-starter-alibaba-seata的依赖.如果xid还无法传递,请确认你是否实现了WebMvcConfigurer,如果是,请参考com.alibaba.cloud.seata.web.SeataHandlerInterceptorConfiguration#addInterceptors的方法.把SeataHandlerInterceptor加入到你的拦截链路中.开启全局事务 在需要事务管理的方法上添加 @GlobalTransaction 注解 开启全局事务 观测到 undo_log 日志记录 {"@class":"io.seata.rm.datasource.undo.BranchUndoLog","xid":"10.3.184.240:8091:244194318322958336","branchId":244194396508979200,"sqlUndoLogs":["java.util.ArrayList",[{"@class":"io.seata.rm.datasource.undo.SQLUndoLog","sqlType":"UPDATE","tableName":"account","beforeImage":{"@class":"io.seata.rm.datasource.sql.struct.TableRecords","tableName":"account","rows":["java.util.ArrayList",[{"@class":"io.seata.rm.datasource.sql.struct.Row","fields":["java.util.ArrayList",[{"@class":"io.seata.rm.datasource.sql.struct.Field","name":"id","keyType":"PRIMARY_KEY","type":-5,"value":["java.lang.Long",1]},{"@class":"io.seata.rm.datasource.sql.struct.Field","name":"password","keyType":"NULL","type":12,"value":"test01"},{"@class":"io.seata.rm.datasource.sql.struct.Field","name":"password_flag","keyType":"NULL","type":-6,"value":1}]]}]]},"afterImage":{"@class":"io.seata.rm.datasource.sql.struct.TableRecords","tableName":"account","rows":["java.util.ArrayList",[{"@class":"io.seata.rm.datasource.sql.struct.Row","fields":["java.util.ArrayList",[{"@class":"io.seata.rm.datasource.sql.struct.Field","name":"id","keyType":"PRIMARY_KEY","type":-5,"value":["java.lang.Long",1]},{"@class":"io.seata.rm.datasource.sql.struct.Field","name":"password","keyType":"NULL","type":12,"value":"test02"},{"@class":"io.seata.rm.datasource.sql.struct.Field","name":"password_flag","keyType":"NULL","type":-6,"value":1}]]}]]}}]]} {"@class":"io.seata.rm.datasource.undo.BranchUndoLog","xid":"10.3.184.240:8091:244189118866587648","branchId":244189121894875136,"sqlUndoLogs":["java.util.ArrayList",[{"@class":"io.seata.rm.datasource.undo.SQLUndoLog","sqlType":"UPDATE","tableName":"article_statistics","beforeImage":{"@class":"io.seata.rm.datasource.sql.struct.TableRecords","tableName":"article_statistics","rows":["java.util.ArrayList",[{"@class":"io.seata.rm.datasource.sql.struct.Row","fields":["java.util.ArrayList",[{"@class":"io.seata.rm.datasource.sql.struct.Field","name":"id","keyType":"PRIMARY_KEY","type":-5,"value":["java.lang.Long",1]},{"@class":"io.seata.rm.datasource.sql.struct.Field","name":"like_num","keyType":"NULL","type":4,"value":500}]]}]]},"afterImage":{"@class":"io.seata.rm.datasource.sql.struct.TableRecords","tableName":"article_statistics","rows":["java.util.ArrayList",[{"@class":"io.seata.rm.datasource.sql.struct.Row","fields":["java.util.ArrayList",[{"@class":"io.seata.rm.datasource.sql.struct.Field","name":"id","keyType":"PRIMARY_KEY","type":-5,"value":["java.lang.Long",1]},{"@class":"io.seata.rm.datasource.sql.struct.Field","name":"like_num","keyType":"NULL","type":4,"value":700}]]}]]}}]]}观测到seata-server 回滚记录 |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |